<template>
  <div class="org-tree">
    <div class="tree-header">
      <span>组织架构</span>
      <el-icon class="refresh-icon" @click="handleRefresh"><refresh /></el-icon>
    </div>
    <el-input
      v-model="searchKeyword"
      class="search-input"
      clearable
      placeholder="搜索部门"
      :prefix-icon="Search"
      @input="handleSearchInput"
    />
    <div v-if="loading" class="loading-container">
      <el-skeleton animated :rows="5" />
    </div>
    <template v-else>
      <el-scrollbar class="tree-scrollbar" height="calc(100vh - 240px)">
        <el-tree
          ref="treeRef"
          v-loading="treeLoading"
          :data="treeData"
          :default-expanded-keys="expandedKeys"
          highlight-current
          lazy
          :load="loadNode"
          node-key="id"
          :props="defaultProps"
          @node-click="handleNodeClick"
        >
          <template #default="{ node, data }">
            <div class="custom-tree-node">
              <el-icon v-if="data.isLeaf"><office-building /></el-icon>
              <el-icon v-else-if="node.expanded"><folder-opened /></el-icon>
              <el-icon v-else><folder /></el-icon>
              <span :title="node.label">{{ node.label }}</span>
              <el-tag v-if="node.loading" class="loading-tag" size="small" type="warning">加载中</el-tag>
            </div>
          </template>
        </el-tree>
        <div class="tree-bottom-safe-area"></div>
      </el-scrollbar>
    </template>
  </div>
</template>

<script setup lang="ts">
import { Folder, FolderOpened, OfficeBuilding, Refresh } from '@element-plus/icons-vue'
import type { ElTree } from 'element-plus'
import { onMounted, ref } from 'vue'
import type { ApiResponse, TreeNode } from './types'
import { getDictionaryByKey } from '/@/api/dictionary'
import request from '/@/utils/request'
const emit = defineEmits(['node-click', 'refresh'])

// 状态变量
const loading = ref(false)
const treeLoading = ref(false)
const treeData = ref<TreeNode[]>([])
const expandedKeys = ref<string[]>([])
const searchTimeout = ref<number | null>(null)
const searchKeyword = ref('')
const currentNodeId = ref('')
const externalRootNode = ref<TreeNode>({
  id: 'external',
  name: '外部人员',
  isExternal: true, // 标记为外部节点
  hasChildren: true,
  isLeaf: false,
})
const externalData = ref<TreeNode[]>([])
const externalDataLoaded = ref(false)

// 树形控件配置
const defaultProps = {
  children: 'children',
  label: 'name',
  isLeaf: 'isLeaf',
}

// 树形控件引用
const treeRef = ref<InstanceType<typeof ElTree>>()

// 转换API数据为树节点数据
const convertToTreeNodes = (rows: any[]): TreeNode[] => {
  return rows.map((item) => ({
    id: item.id,
    name: item.name || item.shortName,
    departmentsId: item.departmentsId,
    parentId: item.parentId,
    level: item.level,
    shortName: item.shortName,
    corpName: item.corpName,
    hasChildren: true, // 默认假设所有部门都有子节点，加载时会更新
    isLeaf: false,
  }))
}

// 转换外部部门数据为树节点数据
const convertExternalToTreeNodes = (departments: any[]): TreeNode[] => {
  return departments.map((dept) => ({
    id: `ext-${dept.id}`,
    name: dept.name,
    parentId: dept.parentId === 0 ? 'external' : `ext-${dept.parentId}`,
    isExternal: true,
    hasChildren: Array.isArray(dept.children) && dept.children.length > 0,
    isLeaf: !Array.isArray(dept.children) || dept.children.length === 0,
    children: Array.isArray(dept.children) && dept.children.length > 0 ? convertExternalToTreeNodes(dept.children) : undefined,
    // 保存原始数据，以便后续使用
    rawData: dept,
  }))
}

// 获取外部部门数据
const loadExternalDepartments = async () => {
  try {
    console.log('正在加载外部部门数据...')
    const response = await request({
      url: '/api/department',
      method: 'get',
    })

    // 正确处理响应数据
    const data = response.data || response
    console.log('外部部门数据获取结果:', data)

    if (data.code === 0 && data.result) {
      // 转换外部部门数据为树节点数据
      externalData.value = convertExternalToTreeNodes(data.result)
      externalDataLoaded.value = true
      console.log('转换后的外部部门树节点:', externalData.value)
    } else {
      console.error('加载外部部门数据失败:', data)
      externalData.value = []
    }
  } catch (error) {
    console.error('加载外部部门数据出错:', error)
    externalData.value = []
  }
}

// 初始化加载顶层部门
const loadInitialDepartments = async () => {
  loading.value = true
  try {
    console.log('正在加载顶层部门...')
    // 发送请求
    const data: ApiResponse<any> = await request({
      url: '/api/employees/departments/list',
      method: 'get',
      params: {
        page: 1,
        limit: 100,
        id: null,
      },
    })

    console.log('顶层部门数据获取结果:', data)
    // 获取排序
    const sort = await getSort()

    if (data.code === 0 && data.result && data.result.rows) {
      const departmentNodes = convertToTreeNodes(data.result.rows)

      // 根据排序规则对部门节点进行排序
      const sortedDepartmentNodes = departmentNodes.sort((a, b) => {
        const aIndex = sort.indexOf(a.name)
        const bIndex = sort.indexOf(b.name)
        // 如果两个节点都在排序列表中，按照排序列表的顺序排序
        if (aIndex !== -1 && bIndex !== -1) {
          return aIndex - bIndex
        }
        // 如果只有一个节点在排序列表中，将其排在前面
        if (aIndex !== -1) return -1
        if (bIndex !== -1) return 1
        // 如果都不在排序列表中，保持原有顺序
        return 0
      })

      // 添加外部人员节点
      treeData.value = [...sortedDepartmentNodes, externalRootNode.value]

      console.log('转换后的树节点:', treeData.value)

      // 加载外部部门数据
      await loadExternalDepartments()

      // 如果没有数据，添加一个提示节点
      if (treeData.value.length === 0) {
        treeData.value = [
          {
            id: 'empty',
            name: '暂无部门数据',
            isLeaf: true,
          },
        ]
      }
    } else {
      // 处理错误情况
      console.error('加载部门数据失败:', data)
      treeData.value = [
        {
          id: 'error',
          name: '加载失败，请刷新重试',
          isLeaf: true,
        },
      ]
    }
  } catch (error) {
    console.error('加载部门数据出错:', error)
    treeData.value = [
      {
        id: 'error',
        name: '加载失败，请刷新重试',
        isLeaf: true,
      },
    ]
  } finally {
    loading.value = false
  }
}

//从字典获取排序
const getSort = async () => {
  const response = await getDictionaryByKey('deptsort')
  console.log('排序:', response)
  // 将字符串转换为数组，并过滤掉空值
  return (response.result.dataJson || '').split('、').filter(Boolean)
}

// 懒加载节点数据
const loadNode = async (node: any, resolve: (data: TreeNode[]) => void) => {
  // 如果是根节点，直接返回已加载的数据
  if (node.level === 0) {
    resolve(treeData.value)
    return
  }

  const { data } = node
  treeLoading.value = true

  try {
    // 处理外部人员节点
    if (data.id === 'external') {
      console.log('加载外部人员子部门')

      // 如果外部数据已加载，直接返回
      if (externalDataLoaded.value) {
        // 只返回顶层的外部部门（parentId === 0 或 parentId === 'external'）
        const topLevelExternalDepts = externalData.value.filter((dept) => dept.parentId === 'external')
        console.log('顶层外部部门:', topLevelExternalDepts)
        resolve(topLevelExternalDepts)
      } else {
        // 重新加载外部部门数据
        await loadExternalDepartments()
        const topLevelExternalDepts = externalData.value.filter((dept) => dept.parentId === 'external')
        console.log('重新加载的顶层外部部门:', topLevelExternalDepts)
        resolve(topLevelExternalDepts)
      }
      return
    }

    // 处理外部部门子节点
    if (data.isExternal && data.id.toString().startsWith('ext-')) {
      console.log('加载外部子部门:', data)

      // 如果节点有原始数据且含有children
      if (data.rawData && Array.isArray(data.rawData.children) && data.rawData.children.length > 0) {
        console.log('使用节点原始数据中的children:', data.rawData.children)
        const children = convertExternalToTreeNodes(data.rawData.children)
        console.log('转换后的外部子部门:', children)
        resolve(children)
        return
      }

      // 如果没有原始数据，尝试从已加载的外部数据中查找子节点
      const children = externalData.value.filter((dept) => dept.parentId === data.id)
      console.log('从已加载数据中查找的外部子部门:', children)

      // 如果找不到子节点，尝试从服务器加载
      if (children.length === 0) {
        try {
          // 从ID中提取真实ID（移除ext-前缀）
          const realId = data.id.toString().replace('ext-', '')
          console.log('尝试从服务器加载外部子部门，ID:', realId)

          const response = await request({
            url: '/api/department',
            method: 'get',
            params: {
              parentId: realId,
            },
          })

          const responseData = response.data || response
          console.log('服务器返回的外部子部门数据:', responseData)

          if (responseData.code === 0 && Array.isArray(responseData.result)) {
            const serverChildren = convertExternalToTreeNodes(responseData.result)
            console.log('从服务器加载的转换后子部门:', serverChildren)

            // 如果服务器返回了子节点，更新节点状态
            if (serverChildren.length > 0) {
              data.hasChildren = true
              data.isLeaf = false
              resolve(serverChildren)
              return
            }
          }

          // 如果服务器也没有返回子节点，标记为叶子节点
          data.hasChildren = false
          data.isLeaf = true
          resolve([])
        } catch (error) {
          console.error('从服务器加载外部子部门出错:', error)
          data.hasChildren = false
          data.isLeaf = true
          resolve([])
        }
      } else {
        // 使用从已加载数据中找到的子节点
        resolve(children)
      }
      return
    }

    console.log('加载子部门:', {
      父部门: data.name,
      父部门ID: data.id,
    })

    // 根据节点ID加载子部门
    const response: ApiResponse<any> = await request({
      url: '/api/employees/departments/list',
      method: 'get',
      params: {
        page: 1,
        limit: 100,
        parentId: data.id, // 使用id作为父级ID
      },
    })

    const responseData = response // 获取响应数据
    console.log('子部门数据获取结果:', responseData)

    if (responseData.code === 0 && responseData.result) {
      const children = convertToTreeNodes(responseData.result.rows)
      console.log('转换后的子节点:', children)

      // 如果没有子节点，标记为叶子节点
      if (children.length === 0) {
        data.isLeaf = true
        console.log('节点没有子部门，标记为叶子节点:', data.name)
        resolve([])
      } else {
        resolve(children)
      }
    } else {
      console.error('加载子部门失败:', responseData)
      resolve([])
    }
  } catch (error) {
    console.error('加载子部门出错:', error)
    resolve([])
  } finally {
    treeLoading.value = false
  }
}

// 搜索部门
const searchDepartments = async (keyword: string) => {
  if (!keyword) {
    // 如果搜索词为空，重新加载初始部门
    await loadInitialDepartments()
    return
  }

  loading.value = true
  try {
    // 搜索内部部门
    const response = await request({
      url: '/api/employees/departments/search',
      method: 'get',
      params: {
        page: 1,
        limit: 50,
        name: keyword,
      },
    })

    const data = response // 获取响应数据
    let internalSearchResults: TreeNode[] = []

    if (data.code === 0 && data.result) {
      internalSearchResults = convertToTreeNodes(data.result.rows)
    }

    // 搜索外部部门
    let externalSearchResults: TreeNode[] = []
    if (externalDataLoaded.value) {
      // 递归搜索所有外部部门
      const searchInExternalDepts = (nodes: TreeNode[]): TreeNode[] => {
        const results: TreeNode[] = []
        for (const node of nodes) {
          if (node.name.includes(keyword)) {
            results.push({ ...node, parentPath: node.name })
          }
          if (node.children) {
            const childResults = searchInExternalDepts(node.children)
            results.push(...childResults)
          }
        }
        return results
      }

      // 在外部部门中搜索
      externalSearchResults = searchInExternalDepts(externalData.value)
    }

    // 合并搜索结果
    const allResults = [...internalSearchResults, ...externalSearchResults]

    // 更新树数据
    if (allResults.length > 0) {
      treeData.value = allResults
    } else {
      // 如果没有搜索结果，显示提示
      treeData.value = [
        {
          id: 'empty-search',
          name: `未找到"${keyword}"相关部门`,
          isLeaf: true,
        },
      ]
    }
  } catch (error) {
    console.error('搜索部门出错:', error)
    treeData.value = [
      {
        id: 'error-search',
        name: '搜索失败，请重试',
        isLeaf: true,
      },
    ]
  } finally {
    loading.value = false
  }
}

// 处理搜索输入
const handleSearchInput = (value: string) => {
  // 防抖处理
  if (searchTimeout.value) {
    clearTimeout(searchTimeout.value)
  }
  searchTimeout.value = setTimeout(() => {
    searchDepartments(value)
  }, 500) as unknown as number
}

// 节点点击事件
const handleNodeClick = (data: any) => {
  // 如果是错误或空提示节点，不触发事件
  if (data.id === 'error' || data.id === 'empty' || data.id === 'error-search' || data.id === 'empty-search') {
    return
  }

  currentNodeId.value = data.id
  emit('node-click', data)
}

// 刷新树
const handleRefresh = async () => {
  searchKeyword.value = ''
  currentNodeId.value = ''
  expandedKeys.value = []
  await loadInitialDepartments()
  emit('refresh')
}

// 初始化
onMounted(() => {
  loadInitialDepartments()
})
</script>

<style scoped>
.org-tree {
  display: flex;
  flex-direction: column;
  width: 300px;
  height: 100%;
  overflow: auto;
  background-color: #fff;
  border-right: 1px solid #ebeef5;
}

.tree-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  font-weight: 500;
  border-bottom: 1px solid #ebeef5;
}

.refresh-icon {
  color: #909399;
  cursor: pointer;
}

.refresh-icon:hover {
  color: #409eff;
}

.search-input {
  width: 100%;
  padding: 12px;
}

.loading-container {
  padding: 16px;
}

.tree-scrollbar {
  overflow: hidden;
}

.tree-bottom-safe-area {
  width: 100%;
  height: 20px; /* 底部安全区域高度 */
}

.custom-tree-node {
  display: flex;
  gap: 4px;
  align-items: center;
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.custom-tree-node .el-icon {
  flex-shrink: 0;
  font-size: 16px;
  color: #909399;
}

.custom-tree-node span {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
}

.loading-tag {
  height: 16px;
  padding: 0 4px;
  margin-left: 4px;
  font-size: 10px;
  line-height: 16px;
}

:deep(.el-tree-node__content) {
  height: 32px;
}

:deep(.el-tree-node.is-current > .el-tree-node__content) {
  background-color: #ecf5ff;
}

:deep(.el-tree-node__expand-icon.expanded) {
  transform: rotate(90deg);
}
:deep(.el-scrollbar__wrap) {
  padding-bottom: 5em !important;
}
</style>
